package com.sse.product.rbac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sse.product.rbac.entity.Menus;
import com.sse.product.rbac.entity.Role;
import com.sse.product.rbac.entity.User;
import com.sse.product.exception.BizRuntimeException;
import com.sse.product.rbac.mapper.UserMapper;
import com.sse.product.rbac.service.IRoleMenusService;
import com.sse.product.rbac.service.IRoleService;
import com.sse.product.rbac.service.IUserRoleService;
import com.sse.product.rbac.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author junyongli
 * @since 2022-07-22
 */
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IRoleMenusService roleMenuService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<Menus> queryMenuByUser(User user) {
        List<Long> roleIds = userRoleService.queryRoleIdByUser(user);
        List<Menus> menusList = new ArrayList<>();
        roleIds.forEach(roleId -> {
            menusList.addAll(roleMenuService.queryMenuByRoleId(roleId));
        });
        return menusList;
    }

    @Override
    public List<Role> queryRoleByUser(User user) {
        List<Long> roleIds = userRoleService.queryRoleIdByUser(user);
        if (!CollectionUtils.isEmpty(roleIds))
            return roleService.queryRoleByIds(roleIds);
        else
            return new ArrayList<>();
    }

    @Override
    @Transactional
    public boolean addUserRole(User user, List<Role> roleList) {
        userRoleService.deleteRoleByUser(user);
        return userRoleService.addRolesByUser(user.getId(), roleList.stream().map(Role::getId).collect(Collectors.toList()));
    }

    @Override
    public IPage queryUserByKeyWord(String userNameLike, Integer pageNo, Integer pageSize) {
        IPage<User> page = new Page<>(pageNo, pageSize);
        return userMapper.selectPage(page,
                new LambdaQueryWrapper<User>()
                        .like(User::getUserName, userNameLike)
                        .or()
                        .like(User::getMobile, userNameLike)
                        .or()
                        .like(User::getCertSn, userNameLike)
        );
    }

    @Override
    @Transactional
    public Integer updateUser(User user) {
        if (StringUtils.hasText(user.getMobile())) {
            User queryUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getMobile, user.getMobile()));
            if (null != queryUser && !queryUser.getId().equals(user.getId()))
                throw new BizRuntimeException("用户的手机号已存在!");
        }
        if (StringUtils.hasText(user.getCertSn())) {
            User queryUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getCertSn, user.getCertSn()));
            if (null != queryUser && queryUser.getId() != user.getId())
                throw new BizRuntimeException("用户CertSn已存在!");
        }
        return userMapper.updateById(user);
    }

    @Override
    @Transactional
    public Integer addUser(User user) {
        if (StringUtils.hasText(user.getMobile())) {
            User queryUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getMobile, user.getMobile()));
            if (null != queryUser)
                throw new BizRuntimeException("用户的手机号已存在!");
        }

        if (StringUtils.hasText(user.getCertSn())) {
            User queryUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getCertSn, user.getCertSn()));
            if (null != queryUser)
                throw new BizRuntimeException("用户CertSn已存在!");
        }
        return userMapper.insert(user);
    }

    @Override
    public Integer deleteUser(User user) {
        return userMapper.deleteById(user);
    }
}
